package com.ytjj.qmyx.mall.service.impl;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.tencentyun.TLSSigAPIv2;
import com.ytjj.common.constants.CopyWriterConstant;
import com.ytjj.common.constants.TokenConstants;
import com.ytjj.common.model.UsersResponse;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.CopyWriterConfigUtil;
import com.ytjj.qmyx.mall.constants.LiveRoomConstant;
import com.ytjj.qmyx.mall.constants.RedisConstants;
import com.ytjj.qmyx.mall.mapper.*;
import com.ytjj.qmyx.mall.model.*;
import com.ytjj.qmyx.mall.model.dto.LiveProductDto;
import com.ytjj.qmyx.mall.model.dto.LiveRoomInfoDto;
import com.ytjj.qmyx.mall.model.request.PageRequest;
import com.ytjj.qmyx.mall.model.response.*;
import com.ytjj.qmyx.mall.service.LiveService;
import com.ytjj.qmyx.mall.utils.FakeUserUtil;
import com.ytjj.qmyx.users.client.UsersClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: TODO
 */

@Service
@Slf4j
public class LiveServiceImpl implements LiveService {

    @Resource
    private LiveProductDao liveProductDao;
    @Resource
    private LiveDao liveDao;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private LiveMapper liveMapper;
    @Resource
    private UsersClient usersClient;
    @Resource
    private FakeUserUtil fakeUserUtil;
    @Resource
    private ProductDao productDao;
    @Resource
    private RedisService redisService;
    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;
    @Value("${quanmingyanxuan.usersig.sdkappid}")
    private long sdkappid;
    @Value("${quanmingyanxuan.usersig.key}")
    private String key;
    @Override
    public List<LiveRoomResponse> getLiveRoomList(PageRequest pageRequest) {
        PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize());
        List<Live> liveRoomList = liveDao.getLiveRoomList();
        List<Live> liveList = Optional.ofNullable(liveRoomList)
                .orElse(new ArrayList<>());
        List<LiveRoomResponse> liveRoomResponseList = liveList.stream()
                .filter(item -> Strings.isNotEmpty(item.getStream()))
                .map(item -> {
                    LiveRoomResponse liveRoomResponse = new LiveRoomResponse(item);
                    // 查询直播间商品列表
                    List<LiveProduct> liveProductList = liveProductDao.getLiveProductListByLiveId(item.getId());
                    // 直播间商品列表获取
                    List<LiveProductDto> LiveProductDtoList = liveProductList.stream()
                            .map(productItem -> {
                                // 根据商品id查询商品信息
                                Product product = productMapper.selectByPrimaryKey(productItem.getProductId());
                                return new LiveProductDto(product);
                            }).collect(Collectors.toList());
                    liveRoomResponse.setLiveProductList(LiveProductDtoList);
                    liveRoomResponse.setProductNum(LiveProductDtoList.size() - 2);
                    return liveRoomResponse;
                })
                .collect(Collectors.toList());
        return liveRoomResponseList;
    }

    @Override
    public LiveInfoResponse getLiveInfo(Integer userId) {
        LiveInfoResponse liveInfoResponse = new LiveInfoResponse();
        Live live = liveDao.getLiveInfoByUserId(userId);
        if (live != null) {
            BeanUtils.copyProperties(live, liveInfoResponse);
        } else {
            return null;
        }
        return liveInfoResponse;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LiveInfoResponse createLiveRoom(UsersResponse currentUser) {
        long originTime = System.currentTimeMillis();
        long realTime = originTime + (5 * 60 * 60 * 1000);
        // 房间号
        String roomId = RandomStringUtils.randomAlphanumeric(8);
        Live live = new Live();
        live.setRoom(roomId);
        live.setIsFake(1);
        live.setStatus(LiveRoomConstant.LIVE_STATUS_OPEN);
        live.setUserId(currentUser.getId());
        live.setNickname(currentUser.getNickname());
        live.setHeadImg(currentUser.getHeadImg());
        live.setCreateTime(new Date());
        live.setHeartbeatTime(new Date(realTime));
        live.setOpenTime(new Date());
        liveMapper.insertSelective(live);
        return new LiveInfoResponse(live);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LiveInfoResponse updateLiveRoom(UsersResponse currentUser) {
        long originTime = System.currentTimeMillis();
        // 5*60*1000ms
        long realTime = originTime + 300000L;
        Live live = liveDao.getLiveInfoByUserId(currentUser.getId());
        live.setHeartbeatTime(new Date(realTime));
        live.setStatus(LiveRoomConstant.LIVE_STATUS_OPEN);
        liveMapper.updateByPrimaryKeySelective(live);
        return new LiveInfoResponse(live);
    }

    @Override
    public LiveRoomInfoResponse getLiveRoomInfo(Integer id, UsersResponse currentUser) {
        Live live = liveDao.getLiveById(id);
        LiveRoomInfoResponse liveRoomInfoResponse = new LiveRoomInfoResponse();
        BeanUtils.copyProperties(live, liveRoomInfoResponse);
        liveRoomInfoResponse.setUserId(live.getUserId());
        liveRoomInfoResponse.setCoverImg(live.getCoverImg());
        String[] summary = copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.LIVE_SHARE_SUMMARY).split(",");
        liveRoomInfoResponse.setShareTitle(summary[0] + currentUser.getNickname() + summary[1]);
        liveRoomInfoResponse.setShareTitle("@" + currentUser.getNickname() + copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.LIVE_SHARE_TITLE));

        // 是否关注
        Integer attentionFlag = usersClient.isAttention(currentUser.getId(), live.getUserId());
        // 假用户
        List<UsersFake> fakeUserList = fakeUserUtil.getFakeUserList();
        // 直播间商品
        List<LiveProduct> liveProducts = Optional.ofNullable(liveProductDao.getLiveProductListByLiveId(live.getId()))
                .orElse(Collections.emptyList());
        liveRoomInfoResponse.setAttentionFlag(attentionFlag);
        liveRoomInfoResponse.setFakeUserResponseList(fakeUserList);
        liveRoomInfoResponse.setProductNum(liveProducts.size());
        return liveRoomInfoResponse;
    }

    @Override
    public LiveAllProductResponse getLiveRoomProducts(Integer liveId, UsersResponse currentUser) {
        List<LiveProduct> liveProductList = liveProductDao.getLiveProductListByLiveId(liveId);
        LiveAllProductResponse liveAllProductResponse = new LiveAllProductResponse();
        if(liveProductList.size() > 0) {
            List<LiveProductResponse> LiveProductResponseList = liveProductList.stream()
                    .sorted(Comparator.comparing(LiveProduct::getSort).reversed())
                    .map(item -> {
                        LiveProductResponse liveProductResponse = new LiveProductResponse();
                        if (LiveRoomConstant.ACTIVITY_PRODUCT_YES.equals(item.getActivityFlag())) {
                            ProductActivity productActivity = productDao.getProductActivity(item.getProductId(), item.getActivityType());
                            productActivity.setSort(item.getSort().intValue());
                            BeanUtils.copyProperties(productActivity, liveProductResponse);
                            liveProductResponse.setIsActivity(1);
                            liveProductResponse.setActivityType(item.getActivityType());
                        } else {
                            Product product = productDao.getProductById(item.getProductId());
                            product.setSort(item.getSort().intValue());
                            BeanUtils.copyProperties(product, liveProductResponse);
                            liveProductResponse.setIsActivity(0);
                        }
                        return liveProductResponse;
                    }).collect(Collectors.toList());
            liveAllProductResponse.setLiveProductResponseList(LiveProductResponseList);
        }
        // 正在讲解的商品
        String explainProductStr = redisService.get(RedisConstants.EXPLAIN_PRODUCT + liveId);
        if(Strings.isNotEmpty(explainProductStr)) {
            LiveProductResponse liveProductResponse = JSONObject.parseObject(explainProductStr, LiveProductResponse.class);
            liveAllProductResponse.setExplainLiveProduct(liveProductResponse);
        }
        return liveAllProductResponse;
    }

    @Override
    public LiveProductResponse getExplainProduct(Integer id) {
        LiveProductResponse liveProductResponse = new LiveProductResponse();
        LiveProduct explainProduct = liveProductDao.getExplainProduct(id);
        if(explainProduct == null) {
            return null;
        }
        if (LiveRoomConstant.ACTIVITY_PRODUCT_YES.equals(explainProduct.getActivityFlag())) {
            ProductActivity productActivity = productDao.getProductActivity(explainProduct.getProductId(), explainProduct.getActivityType());
            productActivity.setSort(explainProduct.getSort().intValue());
            BeanUtils.copyProperties(productActivity, liveProductResponse);
            liveProductResponse.setActivityType(explainProduct.getActivityType());
            liveProductResponse.setIsActivity(1);
        } else {
            Product product = productDao.getProductById(explainProduct.getProductId());
            product.setSort(explainProduct.getSort().intValue());
            BeanUtils.copyProperties(product, liveProductResponse);
            liveProductResponse.setIsActivity(0);
        }
        redisService.delete(RedisConstants.EXPLAIN_PRODUCT + id);
        redisService.set(RedisConstants.EXPLAIN_PRODUCT + id, JSONObject.toJSONString(liveProductResponse));
        redisService.expire(RedisConstants.EXPLAIN_PRODUCT + id, TokenConstants.EXPIRE_SECONDS);
        return liveProductResponse;
    }

    @Override
    public LiveRoomResponse getLiveOn() {
        Live liveOn = liveDao.getLiveOn();
        LiveRoomResponse liveRoomResponse = null;
        Optional<Live> liveRoom = Optional.ofNullable(liveOn);
        if(liveRoom.isPresent()) {
            liveRoomResponse = new LiveRoomResponse(liveOn);
            liveRoomResponse.setLiveOnFlag(true);
        }
        return liveRoomResponse;
    }

    @Override
    public void closeLiveRoom(Integer id) {
        liveDao.closeLiveRoom(id);
    }

    @Override
    public LiveRoomInfoDto getLiveRoomInfos(Integer id, UsersResponse currentUser) {
        Live live = liveMapper.selectByPrimaryKey(id);
        String roomId = live.getRoom();
        // 获取登陆token
        String loginRequestHost = "https://liveroom.qcloud.com/weapp/live_room/login?";
        JSONObject jsonObject = this.sendGetRequest(loginRequestHost, currentUser);
        String token = jsonObject.getString("token");
        // 获取直播间信息
        String roomInfoRequestHost = "https://liveroom.qcloud.com/weapp/live_room/get_anchors?";
        JSONObject roomInfo = this.sendPostRequest(roomInfoRequestHost, currentUser, token, roomId);
        String mixedPlayURL = roomInfo.getString("mixedPlayURL");
        LiveRoomInfoDto liveRoomInfoDto = new LiveRoomInfoDto();
        liveRoomInfoDto.setToken(token);
        liveRoomInfoDto.setMixedPlayURL(mixedPlayURL);
        return liveRoomInfoDto;
    }


    /**
     * 请求腾讯云API
     *
     * @param requestHost 请求
     * @return
     */
    public JSONObject sendGetRequest(String requestHost, UsersResponse currentUser) {
        // String userSig = currentUser.getUserSig();
        TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(sdkappid, key);
        String userDef = String.valueOf(currentUser.getId());
        String userSig = tlsSigAPIv2.genSig(userDef, 100000000);
        Integer userId = currentUser.getId();
        String host = requestHost +
                "sdkAppID=" +sdkappid+
                "&userSig=" +userSig+
                "&userID=" +userId;
        String result = HttpRequest.post(host)
                .header("Content-Type","application/json; charset=UTF-8")
                .execute()
                .body();
        log.info("result: {}", JSONObject.toJSONString(result, true));
        JSONObject jsonObject = JSONObject.parseObject(result);
        return jsonObject;
    }

    public JSONObject sendPostRequest(String requestHost, UsersResponse currentUser, String token, String roomId) {
        Integer userId = currentUser.getId();
        String host = requestHost +
                "userID="+userId+
                "&token="+token;
        Map<String, Object> map = new HashMap<>();
        map.put("roomID", roomId);
        String result = HttpRequest.post(host)
                .body(JSON.toJSONString(map))
                .header("Content-Type","application/json; charset=UTF-8")
                .execute()
                .body();
        log.info("result: {}", JSONObject.toJSONString(result, true));
        JSONObject jsonObject = JSONObject.parseObject(result);
        return jsonObject;
    }

}
